﻿namespace LevelEditors
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.Serialization;

    public class UIPaintTool : MonoBehaviour
    {
        [CompilerGenerated]
        private static Func<Component, IEditable> <>f__am$cacheC;
        [CompilerGenerated]
        private static Func<Model, bool> <>f__am$cacheD;
        [CompilerGenerated]
        private static Func<Instance, bool> <>f__am$cacheE;
        private int deltaIndex;
        private Rect inspectorRect;
        private Vector3 lastClickPos;
        private static Instance lastPickedInstance;
        [FormerlySerializedAs("cursor"), SerializeField]
        private Transform m_cursor;
        [SerializeField]
        private GUISkin m_guiSkin;
        private Vector2 scrollPos;
        private GameObject selected;
        private IEditable[] selectedInspectors;
        private bool showInspector;
        private GUIStyle titleStyle;
        private bool wallsHided;

        private void Erase(Vector3 pos)
        {
            LevelEditor.Instance.Erase(pos);
        }

        private void OnDisable()
        {
            if (this.m_cursor != null)
            {
                this.m_cursor.gameObject.SetActive(false);
            }
        }

        private void OnEnable()
        {
            this.m_cursor.gameObject.SetActive(true);
        }

        private void OnGUI()
        {
            this.selected = null;
            if (this.showInspector && this.hasSelectedInpector)
            {
                if (this.inspectorRect.size == Vector2.zero)
                {
                    this.inspectorRect.size = new Vector2(350f, 100f);
                }
                GUI.skin = this.m_guiSkin;
                Component component = this.selectedInspectors.FirstOrDefault<IEditable>() as Component;
                if (component == null)
                {
                    this.showInspector = false;
                }
                else
                {
                    this.selected = component.gameObject;
                    Vector3 position = component.transform.position;
                    Vector3 vector2 = LevelEditorCamera.Instance.cam.WorldToScreenPoint(position);
                    vector2.y = Screen.height - vector2.y;
                    this.inspectorRect.position = vector2;
                    this.inspectorRect.x -= this.inspectorRect.width / 2f;
                    this.inspectorRect = GUILayout.Window(this.GetHashCode(), this.inspectorRect, delegate (int id) {
                        foreach (IEditable editable in this.selectedInspectors)
                        {
                            GUILayout.Label(editable.GetType().Name, this.titleStyle, new GUILayoutOption[0]);
                            editable.OnEditorGUI();
                        }
                        if (GUIUtility.keyboardControl != 0)
                        {
                            Event current = Event.current;
                            if (!current.shift && (((current.keyCode == KeyCode.Escape) || (current.keyCode == KeyCode.Return)) || (current.keyCode == KeyCode.KeypadEnter)))
                            {
                                GUI.FocusControl(null);
                            }
                        }
                    }, component.name, new GUILayoutOption[0]);
                }
            }
        }

        private void Paint(Vector3 pos)
        {
            if (pos.magnitude != float.NaN)
            {
                Instance instance = LevelEditor.Instance.Paint(pos);
                if (instance != null)
                {
                    if ((lastPickedInstance != null) && (lastPickedInstance.prefabName == instance.prefabName))
                    {
                        instance.SetEulerAngles(lastPickedInstance.eulerAngles);
                        instance.DeserializeComponents(lastPickedInstance.SerializeComponents());
                    }
                    lastPickedInstance = instance;
                }
            }
        }

        private Instance PickInstance()
        {
            IEnumerable<Instance> instances = LevelEditor.Instance.GetInstances(this.m_cursor.position);
            this.deltaIndex = (int) Mathf.Repeat((float) (this.deltaIndex + 1), (float) instances.Count<Instance>());
            Instance instance = instances.ElementAtOrDefault<Instance>(this.deltaIndex);
            lastPickedInstance = instance;
            return instance;
        }

        private Instance PickSelectedPrefabInstance()
        {
            if (<>f__am$cacheE == null)
            {
                <>f__am$cacheE = x => x.prefabName == LevelEditor.Instance.selectedPrefabName;
            }
            Instance instance = LevelEditor.Instance.GetInstances(this.m_cursor.position).FirstOrDefault<Instance>(<>f__am$cacheE);
            if (instance != null)
            {
                lastPickedInstance = instance;
            }
            return instance;
        }

        private void Start()
        {
            this.titleStyle = new GUIStyle();
            this.titleStyle.fontSize = 15;
        }

        private void Update()
        {
            if (this.selected != null)
            {
                OutlineDrawer.Draw(this.selected);
            }
            if (EventSystem.current.IsPointerOverGameObject() || this.isMouseOverGUI)
            {
                this.m_cursor.SetActive(false);
            }
            else
            {
                this.m_cursor.SetActive(true);
                if (Input.GetKeyDown(KeyCode.E))
                {
                    if ((lastPickedInstance != null) && (lastPickedInstance.transform != null))
                    {
                        if (<>f__am$cacheC == null)
                        {
                            <>f__am$cacheC = x => x as IEditable;
                        }
                        this.selectedInspectors = lastPickedInstance.transform.GetComponents(typeof(IEditable)).Select<Component, IEditable>(<>f__am$cacheC).ToArray<IEditable>();
                    }
                    this.showInspector = !this.showInspector;
                }
                if (Input.GetKeyDown(KeyCode.R))
                {
                    Instance instance = this.PickSelectedPrefabInstance();
                    if (instance != null)
                    {
                        instance.SetEulerAngles(instance.eulerAngles + new Vector3(0f, 90f, 0f));
                    }
                }
                if (Input.GetKeyDown(KeyCode.W))
                {
                    if (<>f__am$cacheD == null)
                    {
                        <>f__am$cacheD = x => x.gameObject.layer == GameLayers.Wall.index;
                    }
                    IEnumerator<Model> enumerator = UnityEngine.Object.FindObjectsOfType<Model>().Where<Model>(<>f__am$cacheD).GetEnumerator();
                    try
                    {
                        while (enumerator.MoveNext())
                        {
                            Model current = enumerator.Current;
                            current.instance.gameObject.SetActive(this.wallsHided);
                        }
                    }
                    finally
                    {
                        if (enumerator == null)
                        {
                        }
                        enumerator.Dispose();
                    }
                    this.wallsHided = !this.wallsHided;
                }
                if (!this.showInspector || !this.hasSelectedInpector)
                {
                    this.m_cursor.position = LevelEditor.Snap(Camera.main.GetWorldPositionOnPlaneXZ(Input.mousePosition, 0f));
                    if (Input.GetKey(KeyCode.LeftAlt))
                    {
                        if (Input.GetMouseButtonDown(0))
                        {
                            Instance instance2 = this.PickInstance();
                            if (instance2 != null)
                            {
                                LevelEditor.Instance.selectedPrefabName = instance2.prefabName;
                            }
                        }
                    }
                    else if (Input.GetMouseButton(0))
                    {
                        if (Input.GetKey(KeyCode.LeftShift))
                        {
                            Vector3 vector = this.m_cursor.position - this.lastClickPos;
                            for (float i = 0f; i < vector.magnitude; i++)
                            {
                                Vector3 pos = LevelEditor.Snap(Vector3.Lerp(this.lastClickPos, this.m_cursor.position, i / vector.magnitude));
                                this.Paint(pos);
                            }
                        }
                        this.Paint(this.m_cursor.position);
                        this.lastClickPos = this.m_cursor.position;
                    }
                    if (Input.GetMouseButton(1))
                    {
                        if (Input.GetKey(KeyCode.LeftShift))
                        {
                            Vector3 vector3 = this.m_cursor.position - this.lastClickPos;
                            for (float j = 0f; j < vector3.magnitude; j++)
                            {
                                Vector3 vector4 = LevelEditor.Snap(Vector3.Lerp(this.lastClickPos, this.m_cursor.position, j / vector3.magnitude));
                                this.Erase(vector4);
                            }
                        }
                        this.Erase(this.m_cursor.position);
                        this.lastClickPos = this.m_cursor.position;
                    }
                }
            }
        }

        private bool hasSelectedInpector
        {
            get
            {
                return ((this.selectedInspectors != null) && (this.selectedInspectors.Length > 0));
            }
            set
            {
                if (!value)
                {
                    this.selectedInspectors = null;
                }
            }
        }

        private bool isMouseOverGUI
        {
            get
            {
                return (GUIUtility.hotControl > 0);
            }
        }
    }
}

